#include <iostream>
#include <cmath>
#include <vector>
#include <functional>
#include <fstream>
#include "newton_interpolation.hpp"

const double Pi = acos(-1);

double f(double x){
  return (1./(1 + 25*x*x));
}


void generateData(const std::string& filename, std::function<double(double)> f) {
    int N = 100;
    std::vector<double> x, y;  
    //x.clear();  
    //y.clear();  
    std::ofstream datafile(filename);  
    if (datafile.is_open()) {  
        for (int i = 0; i < N; i++) {  
            x.push_back(-1. + i * 2. / N);  
            y.push_back(f(x[i]));  
            datafile << x[i] << " " << y[i] << std::endl;  
        }  
        datafile.close();  
    } else {  
        std::cerr << "Unable to open file";  
    }  
}  


void NewtonData(const std::string& filename, NewtonInterpolation f) {
    int N = 1000;
    std::vector<double> x, y;  
    //x.clear();  
    //y.clear();  
    std::ofstream datafile(filename);  
    if (datafile.is_open()) {  
        for (int i = 0; i < N; i++) {  
            x.push_back(-1. + i * 2. / N);  
            y.push_back(f.interpolate(x[i]));  
            datafile << x[i] << " " << y[i] << std::endl;  
        }  
        datafile.close();  
    } else {  
        std::cerr << "Unable to open file";  
    }  
}  

int main(){
  std::vector<double> x;
  std::vector<double> y;
  //std::vector<std::function<double(double)>> ip_Functions(4);
  std::vector<std::string> filename = {"data_5.txt","data_10.txt","data_15.txt","data_20.txt"};
  for(int n = 0;n < 4;n++){
    int N = 5*n + 5;
    x.clear();
    y.clear();
    for(int i = 0; i < N; i++){
      x.push_back(cos((2*i+1)*Pi/(2*N)));
      y.push_back(f(x[i]));
    }
    //ip_Functions[n] = Newton_interpolate(x, y);
    NewtonInterpolation f = NewtonInterpolation(x, y);
    NewtonData(filename[n],f);
  }
  
  generateData("data.txt",f);
  /*
  generateData("data_5.txt",ip_Functions[0]);
  generateData("data_10.txt",ip_Functions[1]);
  generateData("data_15.txt",ip_Functions[2]);	
  generateData("data_20.txt",ip_Functions[3]);
  */
}
